<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>
  Class: Statsrb
  
    &mdash; Documentation by YARD 0.8.6.1
  
</title>

  <link rel="stylesheet" href="css/style.css" type="text/css" charset="utf-8" />

  <link rel="stylesheet" href="css/common.css" type="text/css" charset="utf-8" />

<script type="text/javascript" charset="utf-8">
  hasFrames = window.top.frames.main ? true : false;
  relpath = '';
  framesUrl = "frames.html#!" + escape(window.location.href);
</script>


  <script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>

  <script type="text/javascript" charset="utf-8" src="js/app.js"></script>


  </head>
  <body>
    <div id="header">
      <div id="menu">
  
    <a href="_index.html">Index (S)</a> &raquo;
    
    
    <span class="title">Statsrb</span>
  

  <div class="noframes"><span class="title">(</span><a href="." target="_top">no frames</a><span class="title">)</span></div>
</div>

      <div id="search">
  
    <a class="full_list_link" id="class_list_link"
        href="class_list.html">
      Class List
    </a>
  
    <a class="full_list_link" id="method_list_link"
        href="method_list.html">
      Method List
    </a>
  
    <a class="full_list_link" id="file_list_link"
        href="file_list.html">
      File List
    </a>
  
</div>
      <div class="clear"></div>
    </div>

    <iframe id="search_frame"></iframe>

    <div id="content"><h1>Class: Statsrb
  
  
  
</h1>

<dl class="box">
  
    <dt class="r1">Inherits:</dt>
    <dd class="r1">
      <span class="inheritName">Object</span>
      
        <ul class="fullTree">
          <li>Object</li>
          
            <li class="next">Statsrb</li>
          
        </ul>
        <a href="#" class="inheritanceTree">show all</a>
      
      </dd>
    
  
  
    
  
    
  
  
  
    <dt class="r2 last">Defined in:</dt>
    <dd class="r2 last">ext/statsrb/statsrb.c</dd>
  
</dl>
<div class="clear"></div>





  <h2>Instance Attribute Summary <small>(<a href="#" class="summary_toggle">collapse</a>)</small></h2>
  <ul class="summary">
    
      <li class="public ">
  <span class="summary_signature">
    
      <a href="#flush_count-instance_method" title="#flush_count (instance method)">- (Object) <strong>flush_count</strong> </a>
    

    
  </span>
  
  
  
    
    
  
  
  
  
  

  
    <span class="summary_desc"><div class='inline'>
<p>When used with a rack server, the max count of internal events.</p>
</div></span>
  
</li>

    
      <li class="public ">
  <span class="summary_signature">
    
      <a href="#split_file_dir-instance_method" title="#split_file_dir (instance method)">- (Object) <strong>split_file_dir</strong> </a>
    

    
  </span>
  
  
  
    
    
  
  
  
  
  

  
    <span class="summary_desc"><div class='inline'>
<p>The file directory to write when splitting namespaces.</p>
</div></span>
  
</li>

    
  </ul>




  
    <h2>
      Instance Method Summary
      <small>(<a href="#" class="summary_toggle">collapse</a>)</small>
    </h2>

    <ul class="summary">
      
        <li class="public ">
  <span class="summary_signature">
    
      <a href="#call-instance_method" title="#call (instance method)">- (Object) <strong>call</strong> </a>
    

    
  </span>
  
  
  
  
  
  
  

  
    <span class="summary_desc"><div class='inline'>
<p>Returns a rack-compatible response.</p>
</div></span>
  
</li>

      
        <li class="public ">
  <span class="summary_signature">
    
      <a href="#clear-instance_method" title="#clear (instance method)">- (Object) <strong>clear</strong> </a>
    

    
  </span>
  
  
  
  
  
  
  

  
    <span class="summary_desc"><div class='inline'></div></span>
  
</li>

      
        <li class="public ">
  <span class="summary_signature">
    
      <a href="#get-instance_method" title="#get (instance method)">- (Array) <strong>get</strong> </a>
    

    
  </span>
  
  
  
  
  
  
  

  
    <span class="summary_desc"><div class='inline'>
<p>Retrieves internal data based on specified filters.</p>
</div></span>
  
</li>

      
        <li class="public ">
  <span class="summary_signature">
    
      <a href="#initialize-instance_method" title="#initialize (instance method)">- (Object) <strong>initialize</strong> </a>
    

    
  </span>
  
  
    <span class="note title constructor">constructor</span>
  
  
  
  
  
  

  
    <span class="summary_desc"><div class='inline'>
<p>Class constructor, sets up an instance variable.</p>
</div></span>
  
</li>

      
        <li class="public ">
  <span class="summary_signature">
    
      <a href="#length-instance_method" title="#length (instance method)">- (Numeric) <strong>length</strong> </a>
    

    
  </span>
  
  
  
  
  
  
  

  
    <span class="summary_desc"><div class='inline'>
<p>Returns the length of the internal storage.</p>
</div></span>
  
</li>

      
        <li class="public ">
  <span class="summary_signature">
    
      <a href="#load_test-instance_method" title="#load_test (instance method)">- (Object) <strong>load_test</strong> </a>
    

    
  </span>
  
  
  
  
  
  
  

  
    <span class="summary_desc"><div class='inline'></div></span>
  
</li>

      
        <li class="public ">
  <span class="summary_signature">
    
      <a href="#push-instance_method" title="#push (instance method)">- (Statsrb) <strong>push</strong> </a>
    

    
  </span>
  
  
  
  
  
  
  

  
    <span class="summary_desc"><div class='inline'>
<p>Pushes a stat onto the statsrb object.</p>
</div></span>
  
</li>

      
        <li class="public ">
  <span class="summary_signature">
    
      <a href="#query-instance_method" title="#query (instance method)">- (Statsrb) <strong>query</strong> </a>
    

    
  </span>
  
  
  
  
  
  
  

  
    <span class="summary_desc"><div class='inline'>
<p>Locates data from a specified file and loads into internal memory.</p>
</div></span>
  
</li>

      
        <li class="public ">
  <span class="summary_signature">
    
      <a href="#read-instance_method" title="#read (instance method)">- (Statsrb) <strong>read</strong> </a>
    

    
  </span>
  
  
  
  
  
  
  

  
    <span class="summary_desc"><div class='inline'>
<p>Locates data from a specified file and loads into internal memory.</p>
</div></span>
  
</li>

      
        <li class="public ">
  <span class="summary_signature">
    
      <a href="#sort-instance_method" title="#sort (instance method)">- (Statsrb) <strong>sort</strong> </a>
    

    
  </span>
  
  
  
  
  
  
  

  
    <span class="summary_desc"><div class='inline'>
<p>Sorts internal data using a quicksort algorithm based on the hash element's
timestamp.</p>
</div></span>
  
</li>

      
        <li class="public ">
  <span class="summary_signature">
    
      <a href="#split_write-instance_method" title="#split_write (instance method)">- (Statsrb) <strong>split_write</strong> </a>
    

    
  </span>
  
  
  
  
  
  
  

  
    <span class="summary_desc"><div class='inline'>
<p>Writes the in memory data to a separate files based on namespace.</p>
</div></span>
  
</li>

      
        <li class="public ">
  <span class="summary_signature">
    
      <a href="#write-instance_method" title="#write (instance method)">- (Statsrb) <strong>write</strong> </a>
    

    
  </span>
  
  
  
  
  
  
  

  
    <span class="summary_desc"><div class='inline'>
<p>Writes the in memory data to a specified file.</p>
</div></span>
  
</li>

      
    </ul>
  

<div id="constructor_details" class="method_details_list">
  <h2>Constructor Details</h2>
  
    <div class="method_details first">
  <h3 class="signature first" id="initialize-instance_method">
  
    - (<tt>Object</tt>) <strong>initialize</strong> 
  

  

  
</h3><div class="docstring">
  <div class="discussion">
    
<p>Class constructor, sets up an instance variable.</p>


  </div>
</div>
<div class="tags">
  

</div><table class="source_code">
  <tr>
    <td>
      <pre class="lines">


722
723
724
725
726
727
728
729
730
731
732
733
734
735
736</pre>
    </td>
    <td>
      <pre class="code"><span class="info file"># File 'ext/statsrb/statsrb.c', line 722</span>

static VALUE statsrb_constructor(VALUE self) {
  VALUE statsrb_split_file_dir = rb_str_new(&quot;/tmp&quot;, 4);
  rb_iv_set(self, &quot;@split_file_dir&quot;, statsrb_split_file_dir);
  rb_iv_set(self, &quot;@flush_count&quot;, INT2NUM(9));

  // Internal symbols for :ts, :ns and :v.
  VALUE statsrb_key_ts = rb_str_intern(rb_str_new2(&quot;ts&quot;));
  rb_iv_set(self, &quot;@key_ts&quot;, statsrb_key_ts);
  VALUE statsrb_key_ns = rb_str_intern(rb_str_new2(&quot;ns&quot;));
  rb_iv_set(self, &quot;@key_ns&quot;, statsrb_key_ns);
  VALUE statsrb_key_v = rb_str_intern(rb_str_new2(&quot;v&quot;));
  rb_iv_set(self, &quot;@key_v&quot;, statsrb_key_v);

  return self;
}</pre>
    </td>
  </tr>
</table>
</div>
  
</div>

  <div id="instance_attr_details" class="attr_details">
    <h2>Instance Attribute Details</h2>
    
      
      <span id="flush_count=-instance_method"></span>
      <div class="method_details first">
  <h3 class="signature first" id="flush_count-instance_method">
  
    - (<tt>Object</tt>) <strong>flush_count</strong> 
  

  

  
</h3><div class="docstring">
  <div class="discussion">
    
<p>When used with a rack server, the max count of internal events.</p>


  </div>
</div>
<div class="tags">
  

</div>
</div>
    
      
      <span id="split_file_dir=-instance_method"></span>
      <div class="method_details ">
  <h3 class="signature " id="split_file_dir-instance_method">
  
    - (<tt>Object</tt>) <strong>split_file_dir</strong> 
  

  

  
</h3><div class="docstring">
  <div class="discussion">
    
<p>The file directory to write when splitting namespaces. @see #split_write</p>


  </div>
</div>
<div class="tags">
  

</div>
</div>
    
  </div>


  <div id="instance_method_details" class="method_details_list">
    <h2>Instance Method Details</h2>

    
      <div class="method_details first">
  <h3 class="signature first" id="call-instance_method">
  
    - (<tt>Object</tt>) <strong>call</strong> 
  

  

  
</h3><div class="docstring">
  <div class="discussion">
    
<p>Returns a rack-compatible response.</p>


  </div>
</div>
<div class="tags">
  <p class="tag_title">Parameters:</p>
<ul class="param">
  
    <li>
      
        <span class='name'>env</span>
      
      
        <span class='type'>(<tt>Hash</tt>)</span>
      
      
      
    </li>
  
</ul>


</div><table class="source_code">
  <tr>
    <td>
      <pre class="lines">


543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699</pre>
    </td>
    <td>
      <pre class="code"><span class="info file"># File 'ext/statsrb/statsrb.c', line 543</span>

static VALUE statsrb_rack_call(VALUE self, VALUE env) {
  VALUE response = rb_ary_new();
  VALUE headers = rb_hash_new();
  VALUE body = rb_ary_new();

  char *path = RSTRING_PTR(rb_hash_aref(env, rb_str_new2(&quot;PATH_INFO&quot;)));

  rb_hash_aset(headers, rb_str_new2(&quot;Content-Type&quot;), rb_str_new2(&quot;text/json&quot;));

  // Parse the query string
  char *qs = RSTRING_PTR(rb_hash_aref(env, rb_str_new2(&quot;QUERY_STRING&quot;)));
  VALUE query_string = statsrb_parse_qs(qs);

  //const char *method = RSTRING_PTR(rb_hash_aref(env, rb_str_new2(&quot;REQUEST_METHOD&quot;)));
  // @TODO consider moving the request method to the proper REQUEST_METHOD
  const char *method_get = &quot;get&quot;;
  const char *method_getu = &quot;GET&quot;;
  const char *method_put = &quot;put&quot;;
  const char *method_putu = &quot;PUT&quot;;
  // Remove the leading slash.
  path++;
  const char *method = strtok(path, &quot;/\0&quot;);
  if (method &amp;&amp; (strcmp(method, method_put) == 0 || strcmp(method, method_putu) == 0)) {
    long int statsrb_ts, statsrb_v;

    // Get the timestamp, default to now.
    VALUE statsrb_ts_qs = rb_hash_aref(query_string, rb_str_new(&quot;time&quot;, 4));
    if (statsrb_ts_qs != Qnil) {
      statsrb_ts = atoi(RSTRING_PTR(statsrb_ts_qs ));
    }
    else {
      statsrb_ts = (long int)time(NULL);
    }

    // Get the namespace.
    VALUE statsrb_ns = rb_hash_aref(query_string, rb_str_new(&quot;name&quot;, 4));
    if (statsrb_ns == Qnil) {
      statsrb_ns = NULL;
    }

    if (statsrb_ns) {
      // Get the value.
      statsrb_v= 0;
      VALUE statsrb_v_qs = rb_hash_aref(query_string, rb_str_new(&quot;value&quot;, 5));
      if (statsrb_v_qs != Qnil) {
        statsrb_v = atoi(RSTRING_PTR(statsrb_v_qs));
      }

      statsrb_data_push_event(self, RSTRING_PTR(statsrb_ns), statsrb_ts, statsrb_v);

      int data_length = NUM2INT(statsrb_length(self));

      rb_ary_push(body, rb_obj_as_string(INT2NUM(data_length)));

      if (data_length &gt;= NUM2INT(rb_iv_get(self, &quot;@flush_count&quot;))) {
        statsrb_sort(self);
        statsrb_split_write(self, rb_iv_get(self, &quot;@split_file_dir&quot;), rb_str_new2(&quot;a+&quot;));
        statsrb_data_clear_events(self);
      }

      rb_ary_push(body, statsrb_ns);
    }
  }
  else if (method &amp;&amp; (strcmp(method, method_get) == 0 || strcmp(method, method_getu) == 0)) {
    const char * statsrb_str_ns = strtok(NULL, &quot;/\0&quot;);
    if (statsrb_str_ns == NULL) {
      statsrb_str_ns = &quot;data&quot;;
    }

    VALUE jsoncallback = rb_hash_aref(query_string, rb_str_new(&quot;jsoncallback&quot;, 12));
    if (jsoncallback != Qnil) {
      rb_ary_push(body, rb_str_plus(jsoncallback, rb_str_new(&quot;(&quot;, 1)));
    }
    // @TODO move this to a to_json method.
    char json_start[256];
    sprintf(json_start, &quot;{\&quot;%s\&quot;:[&quot;, statsrb_str_ns);
    rb_ary_push(body, rb_str_new2(json_start));

    // If they didn't specify a namespace, bail out immediately.
    if (statsrb_str_ns) {
      VALUE statsrb_ns = rb_str_new2(statsrb_str_ns);
      long int query_limit, query_start, query_end;

      // Get the query limit.
      query_limit = 100;
      VALUE query_limit_qs = rb_hash_aref(query_string, rb_str_new(&quot;limit&quot;, 5));
      if (query_limit_qs != Qnil) {
        query_limit = atoi(RSTRING_PTR(query_limit_qs));
      }

      // Get the query start.
      query_start = 0;
      VALUE query_start_qs = rb_hash_aref(query_string, rb_str_new(&quot;start&quot;, 5));
      if (query_start_qs != Qnil) {
        query_start = atoi(RSTRING_PTR(query_start_qs));
      }

      // Get the query end.
      query_end = 0;
      VALUE query_end_qs = rb_hash_aref(query_string, rb_str_new(&quot;end&quot;, 3));
      if (query_end_qs != Qnil) {
        query_end = atoi(RSTRING_PTR(query_end_qs));
      }

      // Get the past N seconds of data.
      // @TODO the query method fails if we query for data newer than the last entry.
      VALUE query_recent = rb_hash_aref(query_string, rb_str_new(&quot;recent&quot;, 6));
      if (query_recent != Qnil) {
        query_end = (long int)time(NULL);
        long int history = atoi(RSTRING_PTR(query_recent));
        query_start = query_end - history;
      }

      // Create a new Statsrb object to query from.
      VALUE klass = rb_obj_class(self);
      VALUE tmp = rb_class_new_instance(0, NULL, klass);

      statsrb_read(tmp, rb_str_plus(rb_iv_get(self, &quot;@split_file_dir&quot;), statsrb_ns), statsrb_ns, INT2NUM(query_limit), INT2NUM(query_start), INT2NUM(query_end));
      statsrb_sort(tmp);

      int i, data_length = NUM2INT(statsrb_length(tmp));
      StatsrbInternal *internal = statsrb_get_internal(tmp);

      for (i = 0; i &lt; data_length; i++) {
        rb_ary_push(body, rb_str_new(&quot;[&quot;, 1));
        rb_ary_push(body, rb_obj_as_string(INT2NUM(internal-&gt;event_list[i].timestamp)));
        rb_ary_push(body, rb_str_new(&quot;,\&quot;&quot;, 2));
        rb_ary_push(body, rb_str_new2(internal-&gt;ns_list[internal-&gt;event_list[i].ns_index].namespace));
        rb_ary_push(body, rb_str_new(&quot;\&quot;,&quot;, 2));
        rb_ary_push(body, rb_obj_as_string(INT2NUM(internal-&gt;event_list[i].value)));
        rb_ary_push(body, rb_str_new(&quot;]&quot;, 1));

        if (i &lt; data_length - 1) {
          rb_ary_push(body, rb_str_new(&quot;,&quot;, 1));
        }
        rb_ary_push(body, rb_str_new(&quot;\n&quot;, 1));
      }
      statsrb_data_clear_events(tmp);
    }
    rb_ary_push(body, rb_str_new(&quot;]}&quot;, 2));
    if (jsoncallback != Qnil) {
      rb_ary_push(body, rb_str_new(&quot;)&quot;, 1));
    }
  }
  else {
    rb_ary_push(response, INT2NUM(404));
    rb_ary_push(response, headers);
    rb_ary_push(response, body);
    return response;
  }

  rb_ary_push(response, INT2NUM(200));
  rb_ary_push(response, headers);
  rb_ary_push(response, body);

  return response;
}</pre>
    </td>
  </tr>
</table>
</div>
    
      <div class="method_details ">
  <h3 class="signature " id="clear-instance_method">
  
    - (<tt>Object</tt>) <strong>clear</strong> 
  

  

  
</h3>
</div>
    
      <div class="method_details ">
  <h3 class="signature " id="get-instance_method">
  
    - (<tt>Array</tt>) <strong>get</strong> 
  

  

  
</h3><div class="docstring">
  <div class="discussion">
    
<p>Retrieves internal data based on specified filters.</p>


  </div>
</div>
<div class="tags">
  <p class="tag_title">Parameters:</p>
<ul class="param">
  
    <li>
      
        <span class='name'>namespace</span>
      
      
        <span class='type'>(<tt>String</tt>)</span>
      
      
      
    </li>
  
    <li>
      
        <span class='name'>limit</span>
      
      
        <span class='type'>(<tt>Number</tt>)</span>
      
      
      
    </li>
  
    <li>
      
        <span class='name'>start_time</span>
      
      
        <span class='type'>(<tt>Number</tt>)</span>
      
      
      
    </li>
  
    <li>
      
        <span class='name'>end_time</span>
      
      
        <span class='type'>(<tt>Number</tt>)</span>
      
      
      
    </li>
  
</ul>

<p class="tag_title">Returns:</p>
<ul class="return">
  
    <li>
      
      
        <span class='type'>(<tt>Array</tt>)</span>
      
      
      
        &mdash;
        <div class='inline'>
<p>An array of data event hashes.</p>
</div>
      
    </li>
  
</ul>

</div><table class="source_code">
  <tr>
    <td>
      <pre class="lines">


293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354</pre>
    </td>
    <td>
      <pre class="code"><span class="info file"># File 'ext/statsrb/statsrb.c', line 293</span>

static VALUE statsrb_get(VALUE self, VALUE query_ns, VALUE query_limit, VALUE query_start, VALUE query_end) {
  // @TODO maybe it would be sane to make a new statsrb object and then just have
  // methods to dump everything to ary, json, etc.
  StatsrbInternal *internal = statsrb_get_internal(self);
  int tmp_ts, tmp_v, tmp_i;

  VALUE filtered_data = rb_ary_new();
  VALUE rb_ns_list = rb_ary_new();
  VALUE statsrb_event;

  int i = 0;
  int filtered_count = 0;

  int limit = NUM2INT(query_limit);
  int qstart = NUM2INT(query_start);
  int qend = NUM2INT(query_end);

  VALUE rb_ns;

  // Create rb strings for the namespaces.
  signed int found = -1;
  for (i = 0; i &lt; internal-&gt;ns_count; i++) {
    rb_hash_aset(rb_ns_list, INT2NUM(i), rb_str_new2(internal-&gt;ns_list[i].namespace));
    if (strcmp(RSTRING_PTR(query_ns), RSTRING_PTR(rb_hash_aref(rb_ns_list, INT2NUM(i)))) == 0) {
      memcpy(&amp;found, &amp;i, sizeof(int));
    }
  }

  // Return right away if the namespace doesn't exist.
  if (found == -1) {
    rb_ary_resize(filtered_data, (long) 0);
    return filtered_data;
  }

  // Iterate through the in-memory data to find matches.
  for (i = 0; i &lt; internal-&gt;event_count; i++) {
    if (found == internal-&gt;event_list[i].ns_index
        &amp;&amp; (qstart == 0 || internal-&gt;event_list[i].timestamp &gt;= qstart)
        &amp;&amp; (qend == 0 || internal-&gt;event_list[i].timestamp &lt;= qend)) {

      memcpy(&amp;tmp_ts, &amp;internal-&gt;event_list[i].timestamp, sizeof(int));
      memcpy(&amp;tmp_v, &amp;internal-&gt;event_list[i].value, sizeof(int));

      statsrb_event = statsrb_create_rb_event_hash(
        self,
        INT2NUM(tmp_ts),
        rb_hash_aref(rb_ns_list, INT2NUM(found)),
        INT2NUM(tmp_v)
      );

      rb_ary_push(filtered_data, statsrb_event);
      filtered_count++;
    }

    if (limit &gt; 0 &amp;&amp; filtered_count == limit) {
      break;
    }
  }

  rb_ary_resize(filtered_data, filtered_count);
  return filtered_data;
}</pre>
    </td>
  </tr>
</table>
</div>
    
      <div class="method_details ">
  <h3 class="signature " id="length-instance_method">
  
    - (<tt>Numeric</tt>) <strong>length</strong> 
  

  

  
</h3><div class="docstring">
  <div class="discussion">
    
<p>Returns the length of the internal storage.</p>


  </div>
</div>
<div class="tags">
  
<p class="tag_title">Returns:</p>
<ul class="return">
  
    <li>
      
      
        <span class='type'>(<tt>Numeric</tt>)</span>
      
      
      
        &mdash;
        <div class='inline'>
<p>The count of items in the internal storage.</p>
</div>
      
    </li>
  
</ul>

</div><table class="source_code">
  <tr>
    <td>
      <pre class="lines">


102
103
104
105
106
107
108
109</pre>
    </td>
    <td>
      <pre class="code"><span class="info file"># File 'ext/statsrb/statsrb.c', line 102</span>

static VALUE statsrb_length(VALUE self) {
  StatsrbInternal *internal = statsrb_get_internal(self);
  if (!internal-&gt;event_count) {
    internal-&gt;event_count = 0;
  }

  return INT2NUM(internal-&gt;event_count);
}</pre>
    </td>
  </tr>
</table>
</div>
    
      <div class="method_details ">
  <h3 class="signature " id="load_test-instance_method">
  
    - (<tt>Object</tt>) <strong>load_test</strong> 
  

  

  
</h3>
</div>
    
      <div class="method_details ">
  <h3 class="signature " id="push-instance_method">
  
    - (<tt><span class='object_link'><a href="" title="Statsrb (class)">Statsrb</a></span></tt>) <strong>push</strong> 
  

  

  
</h3><div class="docstring">
  <div class="discussion">
    
<p>Pushes a stat onto the statsrb object.</p>


  </div>
</div>
<div class="tags">
  <p class="tag_title">Parameters:</p>
<ul class="param">
  
    <li>
      
        <span class='name'>timestamp</span>
      
      
        <span class='type'>(<tt>Number</tt>)</span>
      
      
      
    </li>
  
    <li>
      
        <span class='name'>namespace</span>
      
      
        <span class='type'>(<tt>String</tt>)</span>
      
      
      
    </li>
  
    <li>
      
        <span class='name'>value</span>
      
      
        <span class='type'>(<tt>Number</tt>)</span>
      
      
      
    </li>
  
</ul>

<p class="tag_title">Returns:</p>
<ul class="return">
  
    <li>
      
      
        <span class='type'>(<tt><span class='object_link'><a href="" title="Statsrb (class)">Statsrb</a></span></tt>)</span>
      
      
      
        &mdash;
        <div class='inline'>
<p>A reference to the object.</p>
</div>
      
    </li>
  
</ul>

</div><table class="source_code">
  <tr>
    <td>
      <pre class="lines">


277
278
279
280
281
282
283</pre>
    </td>
    <td>
      <pre class="code"><span class="info file"># File 'ext/statsrb/statsrb.c', line 277</span>

static VALUE statsrb_push(VALUE self, VALUE timestamp, VALUE namespace, VALUE value) {
  int ts = NUM2INT(timestamp);
  int v = NUM2INT(value);
  const char *ns = RSTRING_PTR(namespace);
  statsrb_data_push_event(self, ns, ts, v);
  return self;
}</pre>
    </td>
  </tr>
</table>
</div>
    
      <div class="method_details ">
  <h3 class="signature " id="query-instance_method">
  
    - (<tt><span class='object_link'><a href="" title="Statsrb (class)">Statsrb</a></span></tt>) <strong>query</strong> 
  

  

  
</h3><div class="docstring">
  <div class="discussion">
    
<p>Locates data from a specified file and loads into internal memory.</p>


  </div>
</div>
<div class="tags">
  <p class="tag_title">Parameters:</p>
<ul class="param">
  
    <li>
      
        <span class='name'>filepath</span>
      
      
        <span class='type'>(<tt>String</tt>)</span>
      
      
      
    </li>
  
    <li>
      
        <span class='name'>namespace</span>
      
      
        <span class='type'>(<tt>String</tt>)</span>
      
      
      
    </li>
  
    <li>
      
        <span class='name'>limit</span>
      
      
        <span class='type'>(<tt>Number</tt>)</span>
      
      
      
    </li>
  
    <li>
      
        <span class='name'>start_time</span>
      
      
        <span class='type'>(<tt>Number</tt>)</span>
      
      
      
    </li>
  
    <li>
      
        <span class='name'>end_time</span>
      
      
        <span class='type'>(<tt>Number</tt>)</span>
      
      
      
    </li>
  
</ul>

<p class="tag_title">Returns:</p>
<ul class="return">
  
    <li>
      
      
        <span class='type'>(<tt><span class='object_link'><a href="" title="Statsrb (class)">Statsrb</a></span></tt>)</span>
      
      
      
        &mdash;
        <div class='inline'>
<p>A reference to the object.</p>
</div>
      
    </li>
  
</ul>

</div><table class="source_code">
  <tr>
    <td>
      <pre class="lines">


365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429</pre>
    </td>
    <td>
      <pre class="code"><span class="info file"># File 'ext/statsrb/statsrb.c', line 365</span>

static VALUE statsrb_read(VALUE self, VALUE logfile, VALUE query_ns, VALUE query_limit, VALUE query_start, VALUE query_end) {
  FILE * file;
  int line_size = 512;
  char *line = (char *) malloc(line_size);
  char *tmp_ns = (char *) malloc(256);
  const char *filepath = RSTRING_PTR(logfile);
  const char *query_ns_char = RSTRING_PTR(query_ns);
  int tmp_v, tmp_ts;

  // Convert into an int that ruby understands.
  int limit = NUM2INT(query_limit);
  int qstart = NUM2INT(query_start);
  int qend = NUM2INT(query_end);

  file = fopen(filepath, &quot;r&quot;);
  if (file == NULL) {
    fprintf(stderr, &quot;File error: could not open file %s for reading.&quot;, filepath);
    return self;
  }

  int count = 0;

  while (NULL != fgets(line, line_size, file) &amp;&amp; count &lt; limit) {
    // strstr doesn't work with newline chars.
    size_t len = strlen(line) - 1;
    if (line[len] == '\n');
        line[len] = '\0';

    // If the namespace is in the row, explode it.
    if (line[0] != '\0' &amp;&amp; line[0] != '\n' &amp;&amp; strchr(line, query_ns_char[0]) &amp;&amp; strstr(line, query_ns_char)) {
      //VALUE statsrb_event = rb_hash_new();

      // I tried sscanf for convenience, but it was predictably slower.
      //int statsrb_ts, statsrb_v;
      //sscanf(line, &quot;%d\t%*s\t%d&quot;, &amp;statsrb_ts, &amp;statsrb_v);

      // @TODO this should something more robust than atoi.
      tmp_ts = atoi(strtok(line, &quot;\t&quot;));

      if (tmp_ts != NULL &amp;&amp; (qstart == 0 || tmp_ts &gt;= qstart) &amp;&amp; (qend == 0 || tmp_ts &lt;= qend)) {
        // @TODO this should probably use the actual namespace if we do wildcard queries.
        strcpy(tmp_ns, strtok(NULL, &quot;\t&quot;));
        //strtok(NULL, &quot;\t&quot;);
        tmp_v = atoi(strtok(NULL, &quot;\0&quot;));

        // @TODO this should really query the namespace exactly instead of just relying on strstr.
        //if (rb_str_cmp(query_ns, statsrb_str_empty) == 0 || rb_str_cmp(query_ns, statsrb_str_ns) == 0) {
        if (tmp_ts &amp;&amp; (tmp_v || tmp_v == 0)) {
          statsrb_data_push_event(self,
            tmp_ns,
            tmp_ts,
            tmp_v);
          count++;
        }
      }
    }
  }

  // terminate
  fclose (file);
  free (line);
  free (tmp_ns);

  return self;
}</pre>
    </td>
  </tr>
</table>
</div>
    
      <div class="method_details ">
  <h3 class="signature " id="read-instance_method">
  
    - (<tt><span class='object_link'><a href="" title="Statsrb (class)">Statsrb</a></span></tt>) <strong>read</strong> 
  

  

  
</h3><div class="docstring">
  <div class="discussion">
    
<p>Locates data from a specified file and loads into internal memory.</p>


  </div>
</div>
<div class="tags">
  <p class="tag_title">Parameters:</p>
<ul class="param">
  
    <li>
      
        <span class='name'>filepath</span>
      
      
        <span class='type'>(<tt>String</tt>)</span>
      
      
      
    </li>
  
    <li>
      
        <span class='name'>namespace</span>
      
      
        <span class='type'>(<tt>String</tt>)</span>
      
      
      
    </li>
  
    <li>
      
        <span class='name'>limit</span>
      
      
        <span class='type'>(<tt>Number</tt>)</span>
      
      
      
    </li>
  
    <li>
      
        <span class='name'>start_time</span>
      
      
        <span class='type'>(<tt>Number</tt>)</span>
      
      
      
    </li>
  
    <li>
      
        <span class='name'>end_time</span>
      
      
        <span class='type'>(<tt>Number</tt>)</span>
      
      
      
    </li>
  
</ul>

<p class="tag_title">Returns:</p>
<ul class="return">
  
    <li>
      
      
        <span class='type'>(<tt><span class='object_link'><a href="" title="Statsrb (class)">Statsrb</a></span></tt>)</span>
      
      
      
        &mdash;
        <div class='inline'>
<p>A reference to the object.</p>
</div>
      
    </li>
  
</ul>

</div><table class="source_code">
  <tr>
    <td>
      <pre class="lines">


365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429</pre>
    </td>
    <td>
      <pre class="code"><span class="info file"># File 'ext/statsrb/statsrb.c', line 365</span>

static VALUE statsrb_read(VALUE self, VALUE logfile, VALUE query_ns, VALUE query_limit, VALUE query_start, VALUE query_end) {
  FILE * file;
  int line_size = 512;
  char *line = (char *) malloc(line_size);
  char *tmp_ns = (char *) malloc(256);
  const char *filepath = RSTRING_PTR(logfile);
  const char *query_ns_char = RSTRING_PTR(query_ns);
  int tmp_v, tmp_ts;

  // Convert into an int that ruby understands.
  int limit = NUM2INT(query_limit);
  int qstart = NUM2INT(query_start);
  int qend = NUM2INT(query_end);

  file = fopen(filepath, &quot;r&quot;);
  if (file == NULL) {
    fprintf(stderr, &quot;File error: could not open file %s for reading.&quot;, filepath);
    return self;
  }

  int count = 0;

  while (NULL != fgets(line, line_size, file) &amp;&amp; count &lt; limit) {
    // strstr doesn't work with newline chars.
    size_t len = strlen(line) - 1;
    if (line[len] == '\n');
        line[len] = '\0';

    // If the namespace is in the row, explode it.
    if (line[0] != '\0' &amp;&amp; line[0] != '\n' &amp;&amp; strchr(line, query_ns_char[0]) &amp;&amp; strstr(line, query_ns_char)) {
      //VALUE statsrb_event = rb_hash_new();

      // I tried sscanf for convenience, but it was predictably slower.
      //int statsrb_ts, statsrb_v;
      //sscanf(line, &quot;%d\t%*s\t%d&quot;, &amp;statsrb_ts, &amp;statsrb_v);

      // @TODO this should something more robust than atoi.
      tmp_ts = atoi(strtok(line, &quot;\t&quot;));

      if (tmp_ts != NULL &amp;&amp; (qstart == 0 || tmp_ts &gt;= qstart) &amp;&amp; (qend == 0 || tmp_ts &lt;= qend)) {
        // @TODO this should probably use the actual namespace if we do wildcard queries.
        strcpy(tmp_ns, strtok(NULL, &quot;\t&quot;));
        //strtok(NULL, &quot;\t&quot;);
        tmp_v = atoi(strtok(NULL, &quot;\0&quot;));

        // @TODO this should really query the namespace exactly instead of just relying on strstr.
        //if (rb_str_cmp(query_ns, statsrb_str_empty) == 0 || rb_str_cmp(query_ns, statsrb_str_ns) == 0) {
        if (tmp_ts &amp;&amp; (tmp_v || tmp_v == 0)) {
          statsrb_data_push_event(self,
            tmp_ns,
            tmp_ts,
            tmp_v);
          count++;
        }
      }
    }
  }

  // terminate
  fclose (file);
  free (line);
  free (tmp_ns);

  return self;
}</pre>
    </td>
  </tr>
</table>
</div>
    
      <div class="method_details ">
  <h3 class="signature " id="sort-instance_method">
  
    - (<tt><span class='object_link'><a href="" title="Statsrb (class)">Statsrb</a></span></tt>) <strong>sort</strong> 
  

  

  
</h3><div class="docstring">
  <div class="discussion">
    
<p>Sorts internal data using a quicksort algorithm based on the hash element's
timestamp.</p>


  </div>
</div>
<div class="tags">
  
<p class="tag_title">Returns:</p>
<ul class="return">
  
    <li>
      
      
        <span class='type'>(<tt><span class='object_link'><a href="" title="Statsrb (class)">Statsrb</a></span></tt>)</span>
      
      
      
        &mdash;
        <div class='inline'>
<p>A reference to the object.</p>
</div>
      
    </li>
  
</ul>

</div><table class="source_code">
  <tr>
    <td>
      <pre class="lines">


165
166
167
168
169
170
171
172</pre>
    </td>
    <td>
      <pre class="code"><span class="info file"># File 'ext/statsrb/statsrb.c', line 165</span>

static VALUE statsrb_sort(VALUE self) {
  StatsrbInternal *internal = statsrb_get_internal(self);
  if (internal-&gt;event_count &gt; 0) {
    time_sort(0, internal-&gt;event_count - 1, internal-&gt;event_list);
  }

  return self;
}</pre>
    </td>
  </tr>
</table>
</div>
    
      <div class="method_details ">
  <h3 class="signature " id="split_write-instance_method">
  
    - (<tt><span class='object_link'><a href="" title="Statsrb (class)">Statsrb</a></span></tt>) <strong>split_write</strong> 
  

  

  
</h3><div class="docstring">
  <div class="discussion">
    
<p>Writes the in memory data to a separate files based on namespace.</p>


  </div>
</div>
<div class="tags">
  <p class="tag_title">Parameters:</p>
<ul class="param">
  
    <li>
      
        <span class='name'>filepath</span>
      
      
        <span class='type'>(<tt>String</tt>)</span>
      
      
      
    </li>
  
    <li>
      
        <span class='name'>filemode</span>
      
      
        <span class='type'>(<tt>String</tt>)</span>
      
      
      
    </li>
  
</ul>

<p class="tag_title">Returns:</p>
<ul class="return">
  
    <li>
      
      
        <span class='type'>(<tt><span class='object_link'><a href="" title="Statsrb (class)">Statsrb</a></span></tt>)</span>
      
      
      
        &mdash;
        <div class='inline'>
<p>A reference to the object.</p>
</div>
      
    </li>
  
</ul>

</div><table class="source_code">
  <tr>
    <td>
      <pre class="lines">


473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503</pre>
    </td>
    <td>
      <pre class="code"><span class="info file"># File 'ext/statsrb/statsrb.c', line 473</span>

static VALUE statsrb_split_write(VALUE self, VALUE logdir, VALUE mode) {
  StatsrbInternal *internal = statsrb_get_internal(self);
  int i, ii, ns_len;

  VALUE filename;
  VALUE klass = rb_obj_class(self);
  VALUE tmp = rb_class_new_instance(0, NULL, klass);

  for (i = 0; i &lt; internal-&gt;ns_count; i++) {
    for (ii = 0; ii &lt; internal-&gt;event_count; ii++) {
      if (strcmp(internal-&gt;ns_list[i].namespace, internal-&gt;ns_list[internal-&gt;event_list[ii].ns_index].namespace) == 0) {
        statsrb_data_push_event(tmp,
          internal-&gt;ns_list[internal-&gt;event_list[ii].ns_index].namespace,
          internal-&gt;event_list[ii].timestamp,
          internal-&gt;event_list[ii].value);
      }
    }

    // If there is no trailing slash on the log dir, add one.
    const char *filepath = RSTRING_PTR(logdir);
    size_t len = strlen(filepath);
    if (filepath[len - 1] != '/') {
      logdir = rb_str_plus(logdir, rb_str_new2(&quot;/&quot;));
    }
    filename = rb_str_new2(internal-&gt;ns_list[i].namespace);
    statsrb_write(tmp, rb_str_plus(logdir, filename), mode);
    statsrb_data_clear_events(tmp);
  }

  return self;
}</pre>
    </td>
  </tr>
</table>
</div>
    
      <div class="method_details ">
  <h3 class="signature " id="write-instance_method">
  
    - (<tt><span class='object_link'><a href="" title="Statsrb (class)">Statsrb</a></span></tt>) <strong>write</strong> 
  

  

  
</h3><div class="docstring">
  <div class="discussion">
    
<p>Writes the in memory data to a specified file.</p>


  </div>
</div>
<div class="tags">
  <p class="tag_title">Parameters:</p>
<ul class="param">
  
    <li>
      
        <span class='name'>filepath</span>
      
      
        <span class='type'>(<tt>String</tt>)</span>
      
      
      
    </li>
  
    <li>
      
        <span class='name'>filemode</span>
      
      
        <span class='type'>(<tt>String</tt>)</span>
      
      
      
    </li>
  
</ul>

<p class="tag_title">Returns:</p>
<ul class="return">
  
    <li>
      
      
        <span class='type'>(<tt><span class='object_link'><a href="" title="Statsrb (class)">Statsrb</a></span></tt>)</span>
      
      
      
        &mdash;
        <div class='inline'>
<p>A reference to the object.</p>
</div>
      
    </li>
  
</ul>

</div><table class="source_code">
  <tr>
    <td>
      <pre class="lines">


438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465</pre>
    </td>
    <td>
      <pre class="code"><span class="info file"># File 'ext/statsrb/statsrb.c', line 438</span>

static VALUE statsrb_write(VALUE self, VALUE logfile, VALUE mode) {
  FILE * file;
  const char *filepath = RSTRING_PTR(logfile);
  const char *filemode = RSTRING_PTR(mode);

  StatsrbInternal *internal = statsrb_get_internal(self);
  int i;

  file = fopen(filepath, filemode);
  if (file==NULL) {
    fprintf(stderr, &quot;File error: could not open file %s mode %s.&quot;, filepath, filemode);
    return self;
  }

  // Iterate through the internal data, writing as we go.
  for (i = 0; i &lt; internal-&gt;event_count; i++) {
    // @TODO make sure that these values are not empty before writing.
    fprintf(file,
            &quot;%d\t%s\t%d\n&quot;,
            internal-&gt;event_list[i].timestamp,
            internal-&gt;ns_list[internal-&gt;event_list[i].ns_index].namespace,
            internal-&gt;event_list[i].value
    );
  }

  fclose (file);
  return self;
}</pre>
    </td>
  </tr>
</table>
</div>
    
  </div>

</div>

    <div id="footer">
  Generated on Fri Jun 28 16:21:38 2013 by
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
  0.8.6.1 (ruby-1.9.3).
</div>

  </body>
</html>